import { mpjLog } from './../utils/helper/log';
import { ChangeDetectorRef } from '@angular/core';
import { NodeService } from './../services/system';
import { Message } from "./common";
import { debounce, throttle } from "app/utils/extended";
export class MessageBoxService {
    constructor() {

    }
    static current: MessageBoxService = new MessageBoxService()
    private container: IMessageBoxContainer
    Regist(container: IMessageBoxContainer) {
        this.container = container;
        this.container.GrowlMessage = [];
    }

    Show(title: string, content: string, showOK = true, showCancel = true, showIgnore = false) {
        this.container.Title = title;
        this.container.Content = content;
        this.container.Visible = true;
        this.container.showOK = showOK;
        this.container.showCancel = showCancel;
        this.container.showIgnore = showIgnore;
        return new Promise<MessageResult>((resolve, reject) => {
            this.container.onResult = (result) => {
                let r: MessageResult;
                switch (result) {
                    case "ok": r = MessageResult.Ok; break;
                    case "cancel": r = MessageResult.Cancel; break;
                    case "ignore": r = MessageResult.Ignore; break;
                    default: break;
                }
                this.container.Visible = false;
                resolve(r);
            }
        });
    }

    Growl(type: GrowlMessageType, title: string, content?: string) {
        if (this.container.GrowlMessage[this.container.GrowlMessage.length - 1] && this.container.GrowlMessage[this.container.GrowlMessage.length - 1].detail == content) {
            return;
        }
        this.container.GrowlMessage.push({ severity: type.Name, summary: title, detail: content });
    }

    nodeServiceWarn(failNodeService) {
        this.container.failNodeService = failNodeService;
    }

    triggerNotOperationonLoading() {
        this.container.isOnLoading = !this.container.isOnLoading;
    }
    refreshKitchenSolutionName() {
        this.container.refreshKitchenSolutionName();
    }

}

export interface IMessageBoxContainer {
    Title: string;
    Content: string;
    Visible: boolean;
    showOK: boolean;
    showCancel: boolean;
    showIgnore: boolean;
    onResult: (result: string) => void;
    GrowlMessage: Message[];
    failNodeService: NodeService;
    isOnLoading: boolean;
    changeDetectorRef: ChangeDetectorRef;
    refreshKitchenSolutionName: () => void;
}

export enum MessageResult {
    Ok,
    Cancel,
    Ignore
}

export class GrowlMessageType {
    static Info: GrowlMessageType = new GrowlMessageType("info", 0);
    static Warning: GrowlMessageType = new GrowlMessageType("warn", 1);
    static Error: GrowlMessageType = new GrowlMessageType("error", 2);
    static Success: GrowlMessageType = new GrowlMessageType("success", 3);

    private name: string;
    private value: number;
    constructor(name: string, value: number) {
        this.name = name;
        this.value = value;
    }

    get Name(): string { return this.name; }
    get Value(): number { return this.value; }
}


export function notOperateOnLoading() {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        let method = descriptor.value;
        descriptor.value = function () {
            MessageBoxService.current.triggerNotOperationonLoading();
            try {
                let that = this;
                let args = arguments;
                var promise = new Promise(function (resolve, reject) {
                    resolve(method.apply(that, args));
                });
                promise.then(function () {
                    MessageBoxService.current.triggerNotOperationonLoading();
                }).catch(function () {
                    MessageBoxService.current.triggerNotOperationonLoading();
                })
                return promise;
            } catch (error) {
                MessageBoxService.current.triggerNotOperationonLoading();
            } finally {

            }
        }
    }
}



export function OperationLock() {
    let flag = true;
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        let method = descriptor.value;
        descriptor.value = async function () {
            if (flag) {
                flag = false;
            } else {
                return;
            }
            try {
                let that = this;
                let args = arguments;
                const result = await method.apply(that, args);
                return result;
            } catch (error) {
                throw error;
            } finally {
                flag = true;
            }
        }
    }
}


export function HandleExpectionErrorUseGrowMessage() {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        let method = descriptor.value;
        let logArgs;
        descriptor.value = async function () {
            try {
                let that = this;
                let args = arguments;
                logArgs = args;
                const result = await method.apply(that, args);
                return result;
            } catch (error) {
                mpjLog.error({
                    source:"HandleExpectionErrorUseGrowMessage",
                    message:error.message || error,
                    stack:error.stack,
                    extended:{propertyKey,error,logArgs}
            });
                MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
            }
        }
    }
}

export function Debounce(wait) {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        let method = descriptor.value;
        descriptor.value = debounce(method,wait || 2000,false)
    }
}

export function Throttle(wait) {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        let method = descriptor.value;
        descriptor.value = throttle(method,wait || 2000,false)
    }
}